'''
Created on May 14, 2014
The Supervised Random Walk implementation
@author: rockyrock
'''

import numpy as np
import mathutils as mu
from numpy import linalg as LA
import graph_utils
from graph_utils import DyadFeaturesIndexLocator

def main():
    pass
    A = [ [0,1,0],
          [1,0,1],
          [0,1,0]
         ]
    A = np.array(A, dtype='float')
    degrees = np.sum(A, axis=1)
    degrees = degrees.reshape(-1, 1)
    P = np.where(degrees != 0, A/degrees, 0)
    print rwr(P, 2, 0.5)
    
def rwr(P, s, c, n_iter=0):
    """
    Computes random walk with restart given:
    P: the transition probability matrix
    s: the index of the starting node
    c: the probability of restart
    n_iter: if > 0, the the method compute RWR using an iterative version,
            otherwise it uses an inverse based method
    
    Returns
    -------
    scores: a vector that represent the probability that 
            the walker is at node i, given that he started from node s.
            
    """
    
    N = P.shape[0]
    q_x = np.zeros((N))
    e_x = np.zeros((N))
    q_x[s] = 1
    e_x[s] = c
    
    if n_iter > 0:
        for i in xrange(n_iter):
            q_x = (1-c) * np.dot(P.T, q_x) + e_x
    else:
        cc = 1-c
        I = np.identity(N)
        e_x[s] = 1
        inv = (I - cc * P.T)
        inv = LA.inv(inv)
        q_x = (1-cc) * inv
        q_x = np.dot(q_x, e_x)
    
    return q_x

class SRW:
    
    def __init__(self, X, T, A, U, nodes_list):
        """
        X: numpy 2D array that holds the features for every dyad
        T: python dictionary that holds as keys the sources,
            and as values a tuple, where one tuple member is a list 
            of the destination nodes (D) and the other is a list
            of non-destination nodes (L).
        A: the adjaceny matrix
        U: the set of all possible edges
        nodes_list: the list of all nodes
        """
        self.X = X
        self.T = T
        self.A = A
        self.w = np.random.random( (X.shape[1]) )
        self.feature_index_locator = DyadFeaturesIndexLocator(U, nodes_list)

    def Q_tick(self, A):
        N = A.shape[0]
        Q = np.zeros((N,N))
        


if __name__ == '__main__':
    main()
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    